#if !defined( MACRO_H )
#define MACRO_H

//########################################################################
#define STRNCPY(to, head, len)	_tcsncpy(to, head, len); *(to+len) = 0;
#define VALID_TCF(tcf)			(tcf && tcf->m_pView)

//########################################################################
//c:\\temp\abc.txt
#define GET_FILE(str)	str.Mid(str.ReverseFind(_T('\\'))+1)	//abc.txt 
#define GET_ROOT(str)		str.Left(str.ReverseFind(_T('\\'))+1)	//c:\\temp\ 
#define GET_TITLE(str)		str.Mid(str.ReverseFind(_T('\\'))+1, str.ReverseFind(_T('.'))-str.ReverseFind(_T('\\'))-1)	//abc

//########################################################################
#define countof(x)			(sizeof(x)/sizeof(x[0]))
#define FREENULL(x);		if (x) { free(x); x=NULL; }
#define SYSFREESTRING(x);	if (x) { SysFreeString(x); x=NULL; }
#define RELEASE(x);			if (x) { x->Release(); x=NULL; }

//########################################################################
#define STR_ERR_PATH_CHAR		_T("\\/:*?\"<>|\r\n")
#define REPLACE_ERR_PATH_CHAR(title)	\
		if (title.FindOneOf(STR_ERR_PATH_CHAR)>=0)	\
		{	\
			title.Replace(_T('\\'), _T('_')); title.Replace(_T('/'), _T('_')); \
			title.Replace(_T(':'), _T('_'));  title.Replace(_T('*'), _T('_')); \
			title.Replace(_T('?'), _T('_'));  title.Replace(_T('\"'), _T('_')); \
			title.Replace(_T('<'), _T('_'));  title.Replace(_T('>'), _T('_')); \
			title.Replace(_T('|'), _T('_'));  title.Replace(_T('\r'), _T('_')); \
			title.Replace(_T('\n'), _T('_'));	\
		}

// http://qwe/123.jpg => 123.jpg
#define GET_URL_NAME(str)	\
		if (IS_URL(str))	\
		{	\
			int pos;	\
			if ( (pos=str.ReverseFind(_T('/'))) >0 || (pos=str.ReverseFind(_T('\\'))) >0 )	\
			{	\
				if (pos < str.GetLength()-1)	\
					str = str.Mid(pos+1);	\
			}	\
		}

// the flag\r\n the content => the flag
#define GET_FILE_NAME(strFileName,str)	\
		int pos = str.FindOneOf(STR_ERR_PATH_CHAR);	\
		if (pos>0)	\
			strFileName = str.Left(pos);	\
		else	\
		{	\
			strFileName = str;	\
			if (pos==0)	\
			{ REPLACE_ERR_PATH_CHAR(strFileName);}	\
		}

#define GET_TAB_TITLE(tcf,strName);	\
		if(tcf->m_strStickName.GetLength()>0)	\
			strName = tcf->m_strStickName;	\
		else	\
			strName = tcf->m_strTitle;

//get insert pos
#define LIST_GET_INSERT_POS(list, p);	\
		POSITION pos = list.GetFirstSelectedItemPosition();	\
		if(pos!=NULL)	\
			*p = list.GetNextSelectedItem(pos)+1;	\
		else	\
			*p= list.GetItemCount();

//focus next after del
#define LIST_FOCUS_POS(list, i);	\
		list.EnsureVisible(i, FALSE);	\
		list.SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);	\
		list.SetFocus();

#define GET_LIST_SEL(list,nCurSel)	\
		POSITION pos = list.GetFirstSelectedItemPosition();	\
		if(pos!=NULL)	\
			nCurSel = m_url.GetNextSelectedItem(pos);	\
		else	\
			nCurSel = -1;

//########################################################################
//sub menu pos
#define SMP_NEW			pmf->GetMenu()->GetSubMenu(0)->GetSubMenu(0)
#define SMP_SAVE		pmf->GetMenu()->GetSubMenu(0)->GetSubMenu(7)
#define SMP_CLOSE		pmf->GetMenu()->GetSubMenu(0)->GetSubMenu(11)

#define SMP_FONTS		pmf->GetMenu()->GetSubMenu(2)->GetSubMenu(4)
#define SMP_ENCODE		pmf->GetMenu()->GetSubMenu(2)->GetSubMenu(5)
#define SMP_UNDO		pmf->GetMenu()->GetSubMenu(2)->GetSubMenu(9)

#define SMP_FAV			pmf->GetMenu()->GetSubMenu(3)

#define SMP_GROUP		pmf->GetMenu()->GetSubMenu(4)

#define SMP_AUTOSCROLL	pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(0)
#define SMP_AUTOFILL	pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(2)
#define SMP_BGCOLOR		pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(3)
#define SMP_DOWNLOAD	pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(4)

#define SMP_SKIN		pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(6)
#define SMP_CLEAN		pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(7)
#define SMP_EXTOOLS		pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(8)

#define SMP_SEARCH		pmf->GetMenu()->GetSubMenu(5)->GetSubMenu(15)

//sub menu handle
#define SMH_FAV			SMP_FAV->m_hMenu

//########################################################################
#define IS_FTP(str)			(str.Left(6)==_T("ftp://") || str.Left(4)==_T("ftp."))
#define IS_DISK_STR(str)	(str.GetAt(1)==':' && (str.GetAt(2)=='\\' || str.GetAt(2)=='/' || str.GetAt(2)==NULL) ) //c: 
#define IS_HTTP(str)		(str.Left(7)==_T("http://") || str.Left(8)==_T("https://"))

#define IS_URL(str)			(	str.Left(7)==_T("http://") || \
								str.Left(7)==_T("file://") || \
								str.Left(8)==_T("https://") || \
								str.Left(7)==_T("file://") || \
								str.Left(4)==_T("www.") || \
								IS_FTP(str) || \
								IS_RES_URL(str) || \
								str==_T("about:blank") || \
								IS_DISK_STR(str) \
							)

#define IS_SCRIPT(str)				(str.Left(11)==_T("javascript:") || str.Left(9)==_T("vbscript:"))
#define IS_MAILTO(str)				(str.Left(7)==_T("mailto:")) // || (str.Find('@')>0 && str.Find('.')>2 && !IS_URL(str)))	//mailto:a@b.com a@b.com
#define IS_SCRIPT_MAILTO(str)		( IS_SCRIPT(str) || IS_MAILTO(str) )
#define IS_SCRIPT_STR(str)			(_tcsstr(str,_T("javascript:")) || _tcsstr(str,_T("vbscript:")))
#define IS_MAILTO_STR(str)			(_tcsstr(str,_T("mailto:")))
#define IS_SCRIPT_MAILTO_STR(str)	(IS_SCRIPT_STR(str) || IS_MAILTO_STR(str))
#define IS_MAIL_STR(str)			(str.Find(_T('@'))>0 && !IS_URL(str) )

//the string should not be search, c:, \\server ror.cn
// not navigate a@b.com
// http://china.qianlong.com/4352/2004/08/18/45@2225131.htm
#define NOT_SEARCH_STR(str)	\
		(	\
			(str.Find(_T('.'))>0 || str.Find(_T('/'))>0 || str.Find(_T('\\'))>=0 || str.Left(2)==_T("\\\\") || IS_DISK_STR(str) )	\
			&&	\
			( !IS_MAIL_STR(str) )	\
		)

// ex: \\app\app1 
//str.Right(1)=='.' means c:\qwe\.  
//shell:ControlPanelFolder
#define IS_LOCAL_FOLDER(str)	\
		(	\
			( str.ReverseFind(_T('.'))<=str.ReverseFind(_T('\\')) || str.ReverseFind(_T('.'))<=str.ReverseFind(_T('/')) || str.Right(1)==_T('.')) &&	\
			( str.Left(5)==_T("file:") || str.Left(2)==_T("\\\\") || str.Left(6)==_T("shell:") || IS_DISK_STR(str))		\
		)

//if have if before, must use { }
#define CLOSE_PAGE(tcf);	\
		if(tcf && !tcf->m_bLock && !tcf->m_pView->m_bToClose)	\
		{	\
			tcf->m_pView->m_bToClose = TRUE;	\
			tcf->PostMessage(WM_CLOSE);	\
		}

//########################################################################
#define LOADSTR(str,id); if (theApp.m_bUseLngFile) _LoadString(str,id); else str.LoadString(id);

#define LOADDLG(strDomain);	if (theApp.m_bUseLngFile) _LoadDlgString(this,strDomain);

#define LOADMENU(pMenu,strDomain); if (theApp.m_bUseLngFile) _LoadMenuString(pMenu,strDomain);

//########################################################################
#define IS_RELATIVE_URL(str)		(str.Left(2)==_T(".\\"))

#define DO_RELATIVE_URL(str);	\
	if ( IS_RELATIVE_URL(str) )	\
	{	\
		str = str.Mid(2);	\
		str = theApp.m_strRoot + str;	\
	}

//########################################################################
#define IS_RES_URL(str)			(str.Left(6)==_T("res://"))

#define DO_RES_URL(str)	\
	int pos = str.Find(_T('#'));	\
	if (pos>0)	\
	{	\
		str = str.Right(str.GetLength()-pos-1); \
		if (str.Left(5)==_T("file:"))	\
		{	\
			str.Replace(_T('\\'), _T('/'));	/*#file://H:\My.htm*/ \
			if (str.Find(_T("file:///")) == -1)	\
			str.Replace(_T("file://"), _T("file:///"));	\
		}	\
	}

#define IS_FAVURL(strUrl)	(strUrl.Right(4).CompareNoCase(_T(".url")) == 0)

//press the key
#define PRESS(k)			(GetKeyState(k)<0)
#define PRESS_CTRL			(GetKeyState(VK_CONTROL)<0)
#define PRESS_SHIFT			(GetKeyState(VK_SHIFT)<0)

//####################################################
#define SAVEINT(from,to,section,entry);	\
	if (to != from )	\
	{	\
		to = from;	\
		theApp.WriteProfileInt(section, entry, to);	\
	}

#define SAVESTR(from,to,section,entry);	\
	if (to != from )	\
	{	\
		to = from;	\
		theApp.WriteProfileString(section, entry, to);	\
	}

//########################################################################
#define CHECK_TAIL(path);	if(path.Right(1) != _T("\\"))	path += _T("\\");

#define CHECK_PATH(path);	\
	if( path.GetLength()<2)		path = _T(".\\");	\
	CHECK_TAIL(path);

//########################################################################


//########################################################################
#endif